define
(    
    function(ko)
    {
        return function()
        {
            var _changeIdToObjectMap = {};
            var _objects = [];

            this.bindingSource = function()
            {
                return _objects;
            }

            this.find = function(changeId)
            {
                return _changeIdToObjectMap[changeId];
            };

            this.add = function(predecessorChangeId, obj)
            {
                var index = -1;
                var objects = _objects;
                for (var i = 0; i < objects.length; i++)
                {
                    if (objects[i].changeId === predecessorChangeId)
                    {
                        index = i;
                        break;
                    }
                }

                _objects.splice(index + 1, 0, obj);
                _changeIdToObjectMap[obj.changeId] = obj;
            };

            this.delete = function(changeId)
            {
                var obj = this.find(changeId);

                if (!obj)
                {
                    return;
                }

                var index = _objects.indexOf(obj);
                _objects.splice(index, 1);
                delete _changeIdToObjectMap[changeId];
            };

            this.updateObject = function(obj)
            {
                var changeId = obj.changeId;
                var obj = this.find(changeId);

                if (!obj)
                {
                    return;
                }

                var index = -1;
                var objects = _objects;
                for (var i = 0; i < objects.length; i++)
                {
                    if (objects[i].changeId === changeId)
                    {
                        index = i;
                        break;
                    }
                }

                _objects[index] = obj;                
                _changeIdToObjectMap[changeId] = obj;                
            };

            this.updateChangeId = function(obj, newChangeId)
            {
                if (newChangeId === obj.changeId)
                {
                    return;
                }

                _changeIdToObjectMap[newChangeId] = obj;
                delete _changeIdToObjectMap[obj.changeId];
                obj.changeId = newChangeId;
            };

            this.reorderObject = function(changeId, newIndex)
            {
                var obj = this.find(changeId);

                if (!obj)
                {
                    return;
                }

                this.delete(changeId);
                _objects.splice(newIndex, 0, obj);
                _changeIdToObjectMap[obj.changeId] = obj;
            };

            this.toJSON = function()
            {
                return _objects;
            }
        }
    }
);